#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>


typedef enum tokentype 
{INTEIRO = 1, REAL, BINARIO, SE, SENAO, ENQUANTO, PARAR, CONTINUAR, RETORNAR, LER, IMPRIMIR, SIM, NAO, E, OU}
TokenType; //No livro está deste jeito

typedef struct
{
	TokenType tokenval;
	char *stringval;
	int numval;
} TokenRecord;

typedef struct tokenode
{
	TokenRecord token;
	struct tokenode *prox;
}TokenNode;

typedef struct tokenlist
{
	TokenNode *Primeiro;
	int numTokens;
}TokenList;

int checarExtensaoValida(char *fName, char** argv);
void getToken(char *Programa, int fSize);
TokenList *initList(void);
void addToken(TokenList *TL, TokenType TT, char *valor, int num);
void carregarPalavrasChaves();
void append(char source, char *destiny);
char tokenAtual[100];
int indiceTA;
int linhaAtual;
int colunaAtual;
char palavrasChaves[20][15];
char simbolosEspeciais[2][6];                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

TokenList TL;

int main(int argc, char **argv)
{
	int fp;
	int tamanho = (int)strlen(argv[1]);
	char *fName = (char*)malloc(sizeof(char)*tamanho);
	int fSize; 
	int freadflag;
	if(argc != 2)
	{
		fprintf(stderr, "Numero invalido de argumentos. digite <out> Code.lambda\n");
	}
	strcpy(fName,argv[1]);
	//printf("A String que eu peguei foi: %s\n", fName);	
	fp = open(fName, O_RDONLY);
	struct stat st;
	stat(fName, &st);
	fSize =  (int)st.st_size;
	char *Programa = (char*)malloc(sizeof(char)*fSize);
	
	freadflag = (int)read(fp,Programa, fSize);
	if(freadflag < 0)
	{
		  fprintf(stderr, "Can't read file\n");
		   exit(1);

	}
	close(fp);
	carregarPalavrasChaves();
	
	getToken(Programa, fSize);
	return 0;
}

void carregarPalavrasChaves()
{
		strcpy(palavrasChaves[0], "INTEIRO");
		strcpy(palavrasChaves[1], "BINARIO");
		strcpy(palavrasChaves[2], "REAL");
		strcpy(palavrasChaves[3], "LER");
		strcpy(palavrasChaves[4], "IMPRIMIR");
		strcpy(palavrasChaves[5], "SE");
		strcpy(palavrasChaves[6], "SENAO");
		strcpy(palavrasChaves[7], "ENQUANTO");
		strcpy(palavrasChaves[8], "RETORNAR");
		strcpy(palavrasChaves[9], "PARAR");
		strcpy(palavrasChaves[10], "CONTINUAR");
		strcpy(palavrasChaves[11], "SIM");
		strcpy(palavrasChaves[12], "NAO");
		strcpy(palavrasChaves[13], "E");
		strcpy(palavrasChaves[14], "OU");
		
		strcpy(simbolosEspeciais[0], ">");
		strcpy(simbolosEspeciais[1], "<");
		strcpy(simbolosEspeciais[2], ">=");
		strcpy(simbolosEspeciais[3], "<=");
		strcpy(simbolosEspeciais[4], "<<");
		strcpy(simbolosEspeciais[5], "<>");
}	

TokenList *initList(void)
{
	TokenList *TL = (TokenList*)malloc(sizeof(TokenList));
	TL->Primeiro = NULL;
	return TL;
}

void addToken(TokenList *TL, TokenType TT, char *valor, int num) //Adiciona na lista encadeada de tokens
{
	TokenRecord *TR = (TokenRecord*)malloc(sizeof(TokenRecord));
	TR->tokenval = TT;
	TR->stringval = valor;
	TR->numval = num;
	TokenNode *TN = (TokenNode*)malloc(sizeof(TokenNode));
	TN->token = *TR;
	if(TL->Primeiro == NULL)
	{
		TL->Primeiro = TN;
		return;
	}
	TokenNode *Aux = TL->Primeiro;
	while(Aux->prox != NULL)
	{
		Aux = Aux->prox;
	}
	Aux->prox = TN;
}

void getToken(char *Programa, int fSize)
{	
	int i=0;
	int j,k;
	int tamanho = 0;
	int wrongEsq =0;
	int wrongDir =0;
	int wrongID = 0;
	linhaAtual = 1;
	colunaAtual = 1;
	int virgula =0; //0 se ainda nao ocorreu virgula, 1 cc
	int ndaVirgula=0; //Numero de digitos antes da virgula
	int ndpVirgula=0; //Numero de digitos apos a virgula
	
	
	while( i < fSize)
	{
			if(Programa[i] >= 65 && Programa[i] <= 90) //Encontrou uma caracter de letra maiuscula
			{
				char *Aux = (char *)malloc(100*sizeof(char)); //OBS:Isso aqui vai virar uma subrotina para evitar repetições
				strcpy(Aux, "\0");
				j = i;
				while((Programa[j] >= 65 && Programa[j] <= 90) || (Programa[j] >= 97 && Programa[j] <= 122) || (Programa[j] >= 48 && Programa[j] <= 57)) 
				{
					append(Programa[j], Aux);
					tamanho++;
					j++;
				}
				char *tokenparcial = (char* )malloc(tamanho*sizeof(char));
				tokenparcial = strtok(Aux, "\0");
				for(k=0; k < 15; k++)
				 {
					if(strcmp(tokenparcial, palavrasChaves[k]) == 0)
					{
						break;
					}
					if(k == 14) {
						printf("LINHA %d: %s\n", linhaAtual, tokenparcial);	
					}
				}
				i = j-1;
				tamanho = 0;
				strcpy(Aux, "\0");
				strcpy(tokenparcial, "\0");
			}
				
			else if(Programa[i] >= 97 && Programa[i] <= 122) //Se ele é um caracter em minusculo, logo deve ser um identificador
			{ 
				
				char *Aux = (char *)malloc(300*sizeof(char));
				strcpy(Aux, "\0");
				j = i;
				while((Programa[j] >=97 && Programa[j] <= 122 ) || (Programa[j] >= 48 && Programa[j] <= 57) || (Programa[j] >= 65 && Programa[j] <= 90))
				{
					if(Programa[j] >= 65 && Programa[j] <= 90)
					{
						wrongID = 1;
					}
					append(Programa[j], Aux);
					tamanho++;
					j++;	
				}
				char *tokenparcial = (char* )malloc(tamanho*sizeof(char));
				tokenparcial = strtok(Aux, "\0");
				if(wrongID==1)
				
					printf("LINHA %d: %s\n", linhaAtual, tokenparcial);
				
				i = j-1;
				tamanho = 0;
				strcpy(Aux, "\0");
				strcpy(tokenparcial, "\0");
				wrongID = 0;
			
			}
			else if ((Programa[i] == 47) || (Programa[i] == 45) || (Programa[i] == 42 ) || (Programa[i] == 43 ) || (Programa[i] == 46 ) || (Programa[i] == 40 ) || (Programa[i] == 41 ) || (Programa[i] == 59 ) || (Programa[i] == 91 ) || (Programa[i] == 93 ) || (Programa[i] == 123 ) || (Programa[i] == 125 ))
				{//Verificar se é um dos caracteres especiais: +-/*();[]{}.
			
				}
			else if(Programa[i] >= 48 && Programa[i] <= 57) //Verificar se ele é numero ou virgula
			{												 //TODO: Colocar para ele verificar uma virgula so
				
				char *Esquerda = (char *)malloc(50*sizeof(char));
				char *Direita = (char *)malloc(50*sizeof(char));
				
				j = i;
				while(((Programa[j] >= 48) && (Programa[j] <= 57)) || (Programa[j] == 44) || (Programa[j] >= 97 && Programa[j] <= 122))
				{
					if(!virgula && Programa[j] != 44) 
					{
						if(Programa[j] >=97 && Programa[j] <=122)
								wrongEsq = 1;
						append(Programa[j], Esquerda);
						ndaVirgula++;
					}
					
					if(Programa[j] == 44 )
					{
						virgula++;
						
					}
					
					if(virgula == 1 && Programa[j] != 44)
					{
						if(Programa[j] >=97 && Programa[j] <=122)
								wrongDir = 1;
						append(Programa[j], Direita);
						ndpVirgula++;
						
					}
					else if(virgula > 1 && Programa[j] == 44)
					{
						printf("LINHA %d: %c\n", linhaAtual, ',');
						break;
			
					}
						tamanho++;
						j++;
				}
				
				if(wrongEsq == 1 && wrongDir == 0 && virgula==1)
				{
					
					
					printf("LINHA %d: %s\n", linhaAtual, Esquerda);
					printf("LINHA %d: %c\n", linhaAtual, ',');
				
				}
				if(wrongDir == 1 && wrongEsq == 0 && virgula==1)
				{
					printf("LINHA %d: %c\n", linhaAtual, ',');
					printf("LINHA %d: %s\n", linhaAtual, Direita);
				}
				
				if(wrongEsq == 1 && wrongDir == 1 &&virgula ==1)
				{
					
					printf("LINHA %d: %s\n", linhaAtual, Esquerda);
					printf("LINHA %d: %c\n", linhaAtual, ',');
					printf("LINHA %d: %s\n", linhaAtual, Direita);
				}
				if((ndaVirgula > 10 || ndpVirgula > 10) && virgula==1)
				{
					append(',', Esquerda);
					strcat(Esquerda,Direita);
					printf("LINHA %d: %s\n", linhaAtual, Esquerda);
				}
				if(ndaVirgula >10 && virgula == 0)
				{
					printf("LINHA %d: %s\n", linhaAtual, Esquerda);
				}
				if(wrongEsq == 1 && virgula == 0 )
				{
					printf("LINHA %d: %s\n", linhaAtual, Esquerda); //problema aqui
				}
				/*	
				char *tokenparcial = (char* )malloc(tamanho*sizeof(char));
				tokenparcial = strtok(Aux, "\0");
				*/
				if(virgula ==1 || virgula==0)
					i = j-1;
				else if(virgula> 1)
					i = j+1;
				tamanho = 0; 
				wrongEsq =0;
				wrongDir = 0;
				virgula = 0;
				ndaVirgula =0;
				ndpVirgula =0;	
				strcpy(Esquerda, "\0");
				strcpy(Direita, "\0");
				
			}
		else if (Programa[i] >= 60 && Programa[i] <=63 ) //Verificar os simbolos >,<, <>, >=, <=, <<
		{
				char *Aux = (char *)malloc(100*sizeof(char)); //OBS:Isso aqui vai virar uma subrotina para evitar repetições
				strcpy(Aux, "\0");
				j = i;
				while(Programa[j] >= 60 && Programa[j] <= 63)
				{
					append(Programa[j], Aux);
					tamanho++;
					j++;
				}
				char *tokenparcial = (char* )malloc(tamanho*sizeof(char));
				tokenparcial = strtok(Aux, "\0");
				for(k=0; k < 6; k++)
				 {
					if(strcmp(tokenparcial, simbolosEspeciais[k]) == 0)
					{

						break;
					}
				}
				i = j-1;
				tamanho = 0;
				strcpy(Aux, "\0");
				strcpy(tokenparcial, "\0");
			}
			else if (Programa[i] == 64)
			{
				char *Aux = (char *)malloc(100*sizeof(char)); //OBS:Isso aqui vai virar uma subrotina para evitar repetições
				strcpy(Aux, "\0");
				j=i+1;
				while(Programa[j] != '\n')
				{
					j++;
				}
				linhaAtual++;
				i=j;
			}
			else if (Programa[i] == '\n')
			{
				linhaAtual++;
				colunaAtual = 0;
			}
			else if(Programa[i] < 0)
			{
				printf("LINHA %d: ? \n", linhaAtual);
			}
			
			else if(Programa[i] != 32 && Programa[i] != '\t' && Programa[i] !='\n' && Programa[i] > 0){
				printf("LINHA %d: %c \n", linhaAtual, Programa[i]);
			}
			
			i++;
		
		}		
			
}

void append(char source, char *destiny)
{
	char aux[2];
	aux[0] = source;
	aux[1] = '\0'; 
	strcat(destiny,aux);
}
